(function ($) {
    /**
     * 将列表数据转换成树的格式
     * @param data
     * @param pid
     * @param isRoot
     * @returns {Array}
     */
    function parseData(data, pid, isRoot) {
        var treeData = [];
        for (var i = 0; i < data.length; i++) {
            var node = dataFilter(data[i]);
            if ((isRoot && !node.pid) || (!isRoot && pid && node.pid && node.pid == pid)) {
                var children = parseData(data, node.id, false);
                if (children.length > 0) {
                    node.children = children;
                    node.icon = "fa fa-folder icon-state-warning icon-lg"
                } else {
                    node.icon = "fa fa-file icon-state-warning icon-lg";
                }
                treeData.push(node);
            }
        }
        return treeData;
    }

    /**
     * 组装成treedata
     * @param it 实体
     */
    function dataFilter(it) {
        it.id = it.mid;
        it.text = it.name;
        if (it.state) {
            it.state.opened = it.opened;
        } else {
            it.state = {"opened": it.opened};
        }
        return it;
    }

    $.fn.czTree = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.czTree.methods[options](this, param);
        }

        var options = options || {};
        return this.each(function () {
            var state = $.data(this, 'czTree');
            var opts;
            if (state) {
                opts = $.extend(state.options, options);
                state.options = opts;
            } else {
                //opts = $.extend({}, $.fn.czTree.defaults, $.fn.czTree.parseOptions(this), options);
                opts = $.extend({}, $.fn.czTree.defaults, options);
                state = $.data(this, 'czTree', {
                    options: opts,
                    data: [],
                    tmpIds: []
                });
                var data = $.fn.czTree.parseData(this);
                if (data.length) {
                    loadData(this, this, data);
                }
            }
            //bindTreeEvents(this);
            if (opts.data) {
                var pid = '', isRoot = true;
                for (var i = 0; i < opts.data.length; i++) {
                    opts.data[i].opened = opts.opened;
                    if (!opts.data[i].pid) {
                        pid = '';
                        isRoot = true;
                        break;
                    } else if (!pid || pid > opts.data[i].pid) {
                        pid = opts.data[i].pid;
                        isRoot = false;
                    }
                }
                opts.core.data = parseData(opts.data, pid, isRoot);
            }
            var jstree = $(this).jstree(opts);
            state.jstree = jstree;
            //request(this, this);
            onChange(this,opts.onChange);
            onClick(this,opts.onClick);
        });
    };

    function onChange(jq,callback) {
        if(callback && typeof callback == "function"){
            $(jq).on("changed.jstree",function (e, node) {
                var data = $(jq).czTree("getSelected");
                callback(e,data);
            });
        }
    }

    function onClick(jq,callback) {
        if(callback && typeof callback == "function"){
            $(jq).on("click.jstree",function (e, node) {
                var id = e.target.id.split('_')[0];
                if(!id){
                    id = $(e.target).parent()[0].id.split('_')[0];
                }
                var data = $(jq).czTree("find",id);
                callback(e,data);
            });
        }
    }

    $.fn.czTree.methods = {
        options: function (jq) {
            return $.data(jq[0], 'czTree').options;
        },
        reload: function (jq, data) {
            jq.each(function () {
                var state = $.data(this, 'czTree');
                var opts = state.options;
                if(data && data.length > 0){
                    opts.data = data;
                }
                var pid = '', isRoot = true;
                for (var i = 0; i < opts.data.length; i++) {
                    opts.data[i].opened = opts.opened;
                    if (!opts.data[i].pid) {
                        pid = '';
                        isRoot = true;
                        break;
                    } else if (!pid || pid > opts.data[i].pid) {
                        pid = opts.data[i].pid;
                        isRoot = false;
                    }
                }
                opts.data = parseData(opts.data, pid, isRoot);
                $(this).jstree({ 'core': { data: null } });
                $(this).jstree(true).settings.core.data =[];
                $(this).jstree(true).refresh();
                $(this).jstree(true).settings.core.data = opts.data;
                $(this).jstree(true).refresh();
            });

        },
        getSelected: function (jq) {
            var selectedData = jq.jstree().get_selected(true);
            var returnData = [];
            if (selectedData) {
                selectedData.forEach(function (item) {
                    returnData.push(item.original);
                    // for (var j = 0; j < originalData.length; j++) {
                    //     if (item == originalData[j].mid) {
                    //         returnData.push(originalData[j]);
                    //         break;
                    //     }
                    // }
                });
            }
            return returnData;
            //return $.data(jq[0], 'tree').jstree.get_selected(true);
        },
        pop: function (jq, nodeEl) {
            var node = jq.czTree('getData', nodeEl);
            jq.czTree('remove', nodeEl);
            return node;
        },
        getParent: function (jq, nodeEl) {
            var id = jq.jstree().get_parent(nodeEl);
            if(id && id != '#'){
                return jq.jstree("get_node", id).original;
            }
            return false;
        },
        find: function (jq, id) {
            return jq.jstree("get_node", id).original;
        },
        select: function (jq, id) {
            jq.jstree('select_node',id,false);
        },
        selectAll: function (jq){
            jq.jstree().select_all(false);
        },
        getChildren: function (jq, nodeEl) {
            var childNodes  = jq.jstree().get_children_dom(nodeEl),
                data = [];
            for (var i = 0; i < childNodes.length; i++) {
                var row = childNodes[i];
                data.push(jq.czTree("find", row.id));
            }
            return data;
        },
        unSelectAll: function (jq){
            jq.jstree().deselect_all(false);
        },
        unSelect: function (jq,obj){
            jq.jstree().deselect_node (obj,false);
        },
        updateNode: function(jq,obj){
            jq.jstree().draw_children (obj);
        },

        //以下方法未实现
        loadData: function (jq, data) {
            return jq.each(function () {
                loadData(this, this, data);
            });
        },
        getNode: function (jq, nodeEl) {	// get the single node
            return getNode(jq[0], nodeEl);
        },
        getData: function (jq, nodeEl) {	// get the specified node data, include its children
            return getData(jq[0], nodeEl);
        },
        getRoot: function (jq, nodeEl) {	// if specify 'nodeEl', return its top parent node, otherwise return the first root node.
            return getRootNode(jq[0], nodeEl);
        },
        getRoots: function (jq) {
            return getRootNodes(jq[0]);
        },
        getChecked: function (jq, state) {	// the state available values are: 'checked','unchecked','indeterminate', default is 'checked'.
            return getCheckedNode(jq[0], state);
        },
        isLeaf: function (jq, nodeEl) {
            return isLeaf(jq[0], nodeEl);
        },
        check: function (jq, nodeEl) {
            return jq.each(function () {
                checkNode(this, nodeEl, true);
            });
        },
        uncheck: function (jq, nodeEl) {
            return jq.each(function () {
                checkNode(this, nodeEl, false);
            });
        },
        collapse: function (jq, nodeEl) {
            return jq.each(function () {
                collapseNode(this, nodeEl);
            });
        },
        expand: function (jq, nodeEl) {
            return jq.each(function () {
                expandNode(this, nodeEl);
            });
        },
        collapseAll: function (jq, nodeEl) {
            return jq.each(function () {
                collapseAllNode(this, nodeEl);
            });
        },
        expandAll: function (jq, nodeEl) {
            return jq.each(function () {
                expandAllNode(this, nodeEl);
            });
        },
        expandTo: function (jq, nodeEl) {
            return jq.each(function () {
                expandToNode(this, nodeEl);
            });
        },
        scrollTo: function (jq, nodeEl) {
            return jq.each(function () {
                scrollToNode(this, nodeEl);
            });
        },
        toggle: function (jq, nodeEl) {
            return jq.each(function () {
                toggleNode(this, nodeEl);
            });
        },
        append: function (jq, param) {
            return jq.each(function () {
                appendNodes(this, param);
            });
        },
        enableDnd: function (jq) {
            return jq.each(function () {
                enableDnd(this);
            });
        },
        disableDnd: function (jq) {
            return jq.each(function () {
                disableDnd(this);
            });
        },
        beginEdit: function (jq, nodeEl) {
            return jq.each(function () {
                beginEdit(this, nodeEl);
            });
        },
        endEdit: function (jq, nodeEl) {
            return jq.each(function () {
                endEdit(this, nodeEl);
            });
        },
        cancelEdit: function (jq, nodeEl) {
            return jq.each(function () {
                cancelEdit(this, nodeEl);
            });
        },
        doFilter: function (jq, q) {
            return jq.each(function () {
                doFilter(this, q);
            });
        }
    };

    $.fn.czTree.parseOptions = function (target) {
        var t = $(target);
        return $.extend({}, $.parser.parseOptions(target, [
            'url', 'method',
            {checkbox: 'boolean', cascadeCheck: 'boolean', onlyLeafCheck: 'boolean'},
            {animate: 'boolean', lines: 'boolean', dnd: 'boolean'}
        ]));
    };

    $.fn.czTree.parseData = function (target) {
        var data = [];
        _parseNode(data, $(target));
        return data;

        function _parseNode(aa, tree) {
            tree.children('li').each(function () {
                var node = $(this);
                var item = $.extend({}, $.parser.parseOptions(this, ['id', 'iconCls', 'state']), {
                    checked: (node.attr('checked') ? true : undefined)
                });
                item.text = node.children('span').html();
                if (!item.text) {
                    item.text = node.html();
                }

                var subTree = node.children('ul');
                if (subTree.length) {
                    item.children = [];
                    _parseNode(item.children, subTree);
                }
                aa.push(item);
            });
        }
    };

    $.fn.czTree.defaults = {
        plugins: ["wholerow", "checkbox", "types"],
        checkbox: {
            undetermined: false,
            three_state: false //保证子节点和父节点选中不冲突，比如选中父节点后，子节点一起选择了；设置这个属性可以屏蔽
        },
        core: {
            multiple: true, //默认可以多选
            themes: {
                responsive: !1
            },
            // data: parseData(data, '', true)
        },
        types: {
            "default": {
                icon: "fa fa-folder icon-state-warning icon-lg"
            },
            file: {
                icon: "fa fa-file icon-state-warning icon-lg"
            }
        },
        opened: false,
        onChange: null,
        onClick: null
    }
})(jQuery);

